﻿/*
 * Copyright 2011 Edward L. Stauff.                     Contact: <EdStauff@gmail.com>.
 * 
 * This file, "ArgValueList.cs", is part of the "Stauffware.Common.Console" class 
 * library.  "Stauffware.Common" is free software: you can redistribute it and/or 
 * modify it under the terms of the GNU Lesser Public License as published by the 
 * Free Software Foundation, either version 3 of the License, or (at your option) 
 * any later version.
 * 
 * "Stauffware.Common" is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Public License for more 
 * details.
 * 
 * You should have received a copy of the GNU Lesser Public License along with 
 * "Stauffware.Common".  If not, see <http://www.gnu.org/licenses/>.
 */

using System;
using System.Collections.Generic;
using System.Text;
using Stauffware.Common.Core;

namespace Stauffware.Common.Console
{
	/// <summary>
	/// Manages a list of command-line argument values.
	/// </summary>
	internal class ArgValueList
	{
		/// <summary>
		/// Gets the Nth arg value in the list, relative to the current one
		/// (for which N = 0).  Thus, negative values can be valid.
		/// </summary>
		/// <param name="n"></param>
		public string this[int n]
		{
			get
			{
				Require.Condition(n >= - this.Consumed, "n must be >= (- Consumed)");
				Require.Condition(n < this.Remaining, "n must be < Remaining");
				return this.ProgramArgs[n + this.Consumed];
			}
		}

		/// <summary>
		/// Gets the number of arg values remaining, including the current one ([0]).
		/// </summary>
		public int Remaining { get { return this.ProgramArgs.Count - this.Current; } }

		/// <summary>
		/// Gets the number of arg values that have already been consumed; that is,
		/// the number of times Next has been called.
		/// </summary>
		public int Consumed { get { return this.Current; } }

		/// <summary>
		/// Gets the total number of arg values in the list, which is always equal
		/// to Consumed + Remaining.
		/// </summary>
		public int Total { get { return this.ProgramArgs.Count; } }

		private readonly IList<string> ProgramArgs;
		private int Current = 0;	// starts at 0, increments up to ProgramArgs.Length

		//-----------------------------------------------------------------------------

		/// constructor
		public ArgValueList (IList<string> programArgs)
		{
			Require.NotNull(programArgs);
			this.ProgramArgs = programArgs;
		}

		/// <summary>
		/// Advances Current to the next arg value (if any).
		/// </summary>
		public void Next ( )
		{
			if (this.Current < this.ProgramArgs.Count)
			{
				this.Current++;
				this.toStringCache = null;
			}
		}

		/// just for debugging
		public override string ToString ( )
		{
			if (this.toStringCache == null)
			{
				ListString ls = new ListString("  ", "(empty)");
				for (int i = 0; i < this.ProgramArgs.Count; i++)
					if (i == this.Current)
						ls.Add(">" + ErrorUtils.ValueToString(this.ProgramArgs[i]) + "<");
					else ls.Add(ErrorUtils.ValueToString(this.ProgramArgs[i]));
				this.toStringCache = "[" + this.Consumed.ToString() + "|" + 
							this.Remaining.ToString() + "]  " + ls.ToString();
			}

			return this.toStringCache;
		}

		private string toStringCache;
	}
}
